using System;
using System.Collections;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using UnityEngine;

public static class Tool
{


    /// <summary>
    /// 获取特效随机位置
    /// </summary>
    /// <param name="deployer"></param>
    /// <param name="hitPosition"></param>
    /// <param name="randomPosition"></param>
    /// <param name="effectRotation"></param>
    public static void GetEffectRandomPosAndRotation(Entity deployer, Vector3 hitPosition, out Vector3 randomPosition, out Quaternion effectRotation)
    {
        // 随机偏移位置
        float positionOffset = 0.2f;
        randomPosition = hitPosition + new Vector3(
            UnityEngine.Random.Range(-positionOffset, positionOffset),
            UnityEngine.Random.Range(-positionOffset, positionOffset)
        );

        // 随机旋转角度，只需要在Z轴上旋转
        float rotationRange = 15f;
        float randomRotationZ = UnityEngine.Random.Range(-rotationRange, rotationRange);
        // 最终旋转角度，包含法线角度和随机偏移
        effectRotation = Quaternion.Euler(0, deployer.facingRight ? 0 : 180, randomRotationZ);
    }

    /// <summary>
    /// 获取实体的中心点
    /// </summary>
    /// <param name="deployer"></param>
    /// <returns></returns>
    public static Vector3 GetEntityCenterByCollider(Transform deployer)
    {
        CapsuleCollider2D collider = deployer.GetComponent<CapsuleCollider2D>();

        // 获取碰撞体的局部中心点
        Vector3 localCenter = collider.offset;
        // 加上碰撞体高度的一半，得到中心位置
        localCenter.y += collider.size.y / 2f;

        // 转换到世界坐标
        Vector3 worldCenter = deployer.TransformPoint(localCenter);

        return worldCenter;
    }

    /// <summary>
    /// 获取获取武器前端位置   碰撞盒最左或最右顶点
    /// </summary>
    /// <param name="collider"></param>
    /// <param name="facingRight"></param>
    /// <returns></returns>
    public static Vector3 GetCollider2DEdgePoint(Collider2D collider, bool facingRight)
    {
        // 获取碰撞器的包围盒
        Bounds bounds = collider.bounds;

        // 计算面向的方向向量（右或左）
        Vector2 attackDirection = facingRight ? Vector2.right : Vector2.left;

        // 根据面向方向和碰撞器的边界来获取边缘点
        Vector3 edgePoint = bounds.center + (Vector3)(attackDirection * bounds.extents.x);

        // 如果需要在局部空间中获取边缘点，需要将世界坐标转换为局部坐标
        // edgePoint = deployer.InverseTransformPoint(edgePoint);

        return edgePoint;
    }


    /// <summary>
    /// 图层检测
    /// </summary>
    /// <param name="obj"></param>
    /// <param name="layermask"></param>
    /// <returns></returns>
    static public bool IsInLayerMask(GameObject obj, LayerMask layermask)
    {
        return ((1 << obj.layer) & layermask) != 0;
    }

    /// <summary>
    /// 找最近的敌人
    /// </summary>
    /// <param name="owner"></param>
    /// <param name="range"></param>
    /// <returns></returns>
    public static Transform FindClosestEnemy(Transform owner, float range = 10f)
    {
        var targets = Physics2D.OverlapCircleAll(owner.position, range);

        float closestDistance = float.MaxValue;
        Transform closestTarget = null;

        foreach (var target in targets)
        {
            if (target.GetComponent<Enemy>() == null)
                continue;
            float distance = Vector3.Distance(target.transform.position, owner.position);

            if (distance < closestDistance)
            {
                closestDistance = distance;
                closestTarget = target.transform;
            }
        }
        return closestTarget;
    }

    /// <summary>
    /// 获取鼠标相对玩家方向
    /// </summary>
    /// <returns></returns>
    public static Vector2 GetMouseDirection()
    {
        Vector2 playerPos = GameMgr.Instance.player.transform.position;
        Vector2 mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
        Vector2 direction = mousePos - playerPos;
        return direction;
    }

    /// <summary>
    /// 射线检测，根据类型
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="action"></param>
    public static void AttackColliderCheck<T>(
        Action<T> action,
        Transform attackCheck,
        float attckCheckRadius
    )
        where T : Entity
    {
        Collider2D[] colliders = Physics2D.OverlapCircleAll(attackCheck.position, attckCheckRadius);

        foreach (Collider2D hit in colliders)
        {
            if (hit.TryGetComponent<T>(out T entity))
            {
                action?.Invoke(entity);
            }
        }
    }

    /// <summary>
    /// 根据当前重力计算达到指定高度需要的力
    /// 重力其实只影响滞空时间
    /// </summary>
    /// <param name="jumpHeight"></param>
    /// <param name="rb"></param>
    /// <returns></returns>
    public static float GetJumpForce(float jumpHeight, Rigidbody2D rb)
    {
        //计算跳跃到height所需要的力，虽然这种计算方法会有一定的误差，但是总能保证物体固定跳到某一个高度
        return Mathf.Sqrt(jumpHeight * (Physics2D.gravity.y * rb.gravityScale) * (-2)) * rb.mass;
    }

    public static bool CheckNumberField(string str)
    {
        // 使用正则表达式判断输入的内容是否都为数字
        Regex reg = new Regex(@"^[0-9]*$");
        if (!reg.IsMatch(str) || string.IsNullOrEmpty(str))
        {
            return false;
        }
        if (!reg.IsMatch(str))
        {
            // 如果输入的内容不全为数字，则清空输入框的内容
            return false;
        }
        return true;
    }

    public static float ConvertSoundVolume(float volume)
    {
        return volume * 100 - 80;
    }

    #region  农场

    /// <summary>
    /// 通过物理方法 获取鼠标点击位置的农作物
    /// </summary>
    /// <param name="mouseWorldPos"></param>
    /// <returns></returns>
    // public static Crop GetCropObject(Vector3 mouseWorldPos)
    // {
    //     // 返回点击目标的所有碰撞器
    //     Collider2D[] colliders = Physics2D.OverlapPointAll(mouseWorldPos);

    //     foreach (var collider in colliders)
    //     {
    //         if (collider.TryGetComponent(out Crop crop))
    //         {
    //             return crop;
    //         }
    //     }
    //     return null;
    // }

    /// <summary>
    /// 通过物理方法 获取npc
    /// </summary>
    /// <param name="mouseWorldPos"></param>
    /// <returns></returns>
    // public static NpcMove GetNpcObject(Vector3 mouseWorldPos)
    // {
    //     // 返回点击目标的所有碰撞器
    //     Collider2D[] colliders = Physics2D.OverlapPointAll(mouseWorldPos);

    //     foreach (var collider in colliders)
    //     {
    //         if (collider.TryGetComponent(out NpcMove npc))
    //         {
    //             return npc;
    //         }
    //     }
    //     return null;
    // }

    /// <summary>
    /// 高效检测
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="raius"></param>
    /// <returns></returns>
    // public static List<T> HasItemsInRadius<T>(float raius)
    // {
    //     var items = new List<T>();
    //     Collider2D[] colliders = new Collider2D[10];
    //     // 可以重复使用已经分配的碰撞器数组，而不是每次调用时都创建一个新的数组。这样可以减少垃圾回收的压力
    //     Physics2D.OverlapCircleNonAlloc(
    //         Camera.main.ScreenToWorldPoint(Input.mousePosition),
    //         raius,
    //         colliders
    //     );

    //     foreach (var collider in colliders)
    //     {
    //         if (collider.TryGetComponent(out T item))
    //         {
    //             items.Add(item);
    //         }
    //     }

    //     return items;
    // }

    /// <summary>
    /// 获取生长阶段
    /// </summary>
    /// <returns></returns>
    // public static int GetCurrentStage(CropDetails cropDetails, TileDetails tileDetails)
    // {
    //     int growthStages = cropDetails.growthDays.Length;
    //     int currentStage = 0;
    //     int dayCounter = cropDetails.TotalGrowthDays;

    //     //倒序计算成长阶段
    //     for (int i = growthStages - 1; i >= 0; i--)
    //     {
    //         if (tileDetails.growthDays >= dayCounter)
    //         {
    //             currentStage = i;
    //             break;
    //         }
    //         dayCounter -= cropDetails.growthDays[i];
    //     }

    //     return currentStage;
    // }

    #endregion
}
